//////////////////////////////////////////////////////////////////////
//
//  is_all_zeros_cimp.cpp
//
//  The C-mex implementation of is_all_zeros
//
//  Created by Dahua Lin, on Dec 23, 2007
//
//////////////////////////////////////////////////////////////////////

#include "mex.h"


bool is_all_zeros(const char *psrc, int nbytes)
{    
    // scan the main part 32-bit wise
    int nints = nbytes >> 2;
    
    const int *p = reinterpret_cast<const int*>(psrc);
    const int *pe = p + nints;

    for(; p != pe && !*p; ++p);

    if (p != pe) return false;

    // scan the remaining bytes
    const char *pend = psrc + nbytes;
    const char *pb = psrc + (nints << 2);
    for(; pb != pend && !*pb; ++pb);

    return pb == pend;
}


/*
 * the main entry
 *
 * Input:  a logical or numeric array
 * Output: a logical scalar
 *
 * For efficiency, no checking inside
 */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    // take input
    const mxArray* mxA = prhs[0];

    int n = (int)mxGetNumberOfElements(mxA);
    int nbytes = n * (int)mxGetElementSize(mxA);

    // scan
    bool b = is_all_zeros(reinterpret_cast<const char*>(mxGetData(mxA)), nbytes);

    // output
    plhs[0] = mxCreateLogicalScalar(b);
}
